/*
*  Delta Robot Clock
*  =================
*
*  STM32 Design Challenge 2011
*
*  Author: Layout
*  URL:    http://www.stm32challenge.com/detail/138
*/

/* Includes ------------------------------------------------------------------*/
#include "stm32f10x_conf.h"
#include "Interrupts.h"
#include "Buttons.h"
#include "Clock.h"

int __errno = 0;

/* Private variables ---------------------------------------------------------*/
volatile uint32_t __delay;

/* Private function prototypes -----------------------------------------------*/
static void _Delay(uint32_t nTime);
static void _OnSysTick(void);

/* Entry point --------------------------------------------------------------*/
static int main(void)
{
	SystemInit();

	/* Start the real time clock ---------------------------------------------*/
    Clock_StartRTC();

    /* Setup SysTick Timer for 1 msec interrupts -----------------------------*/
    SysTick_Config(SystemCoreClock / 1000);
    Interrupts_RegisterCallback(INTERRUPTS_SysTick, _OnSysTick);

    _Delay(1000); // found to be necessary during testing - reason unknown

    /* Initialise other modules ----------------------------------------------*/
    Buttons_Init();
    Clock_Init();    

    Clock_BeginCalibration();
    while (!Buttons_IsPressed(BUTTONS_Blue))
    {
    	Clock_UpdateCalibration();
    }
    Clock_EndCalibration();

    Clock_SetTime(0);
    Clock_SetAlarm(0);

    while (TRUE)
    {
    	//Display_SetState(DISPLAY_SettingTime);
    	_Delay(100);

    	// await release
    	while (Buttons_IsPressed(BUTTONS_Blue))
    	{
    		Clock_Refresh();
    	}

    	uint32_t oldtime = ((Clock_GetTime() / 60) % (24 * 60)) * 60;
		uint32_t time = oldtime;
    	uint32_t alarm = ((Clock_GetAlarm() / 60) % (24 * 60)) * 60;
    	while (!Buttons_IsPressed(BUTTONS_Blue))
    	{
    		bool anypressed = FALSE;
    		if (Buttons_IsPressed(BUTTONS_LeftRed))
    		{
    			uint16_t hour = alarm / 3600;
    			uint16_t minute = (alarm % 3600) / 60;
    			if (Buttons_IsPressed(BUTTONS_LeftBlack))
    			{
    				hour = (hour + 1) % 24;
    				anypressed = TRUE;
    			}
    			if (Buttons_IsPressed(BUTTONS_RightBlack))
    			{
    				minute = (minute + 1) % 60;
    				anypressed = TRUE;
    			}

    			alarm = hour * 3600 + minute * 60;
    			Display_SetTime(alarm);
    		}
    		else
    		{
    			uint16_t hour = time / 3600;
    			uint16_t minute = (time % 3600) / 60;
				if (Buttons_IsPressed(BUTTONS_LeftBlack))
				{
					hour = (hour + 1) % 24;
					anypressed = TRUE;
				}
				if (Buttons_IsPressed(BUTTONS_RightBlack))
				{

					minute = (minute + 1) % 60;
					anypressed = TRUE;
				}

				time = hour * 3600 + minute * 60;
				Display_SetTime(time);
    		}
    		if (anypressed)
    		{
    			Display_Update();
    			_Delay(250); // debounce & limit repeat
    		}

    		Clock_Refresh();
    	}

		if (time != oldtime)
		{
    	    Clock_SetTime(time);
			_Delay(1000); // delay while RTC is set
		}
    	Clock_SetAlarm(alarm);

    	Clock_SetNextState();
    	Display_SetState(DISPLAY_Normal);

    	while (Clock_GetState() == CLOCK_Running)
    	{
    		_Delay(100); // debounce
			while (Buttons_IsPressed(BUTTONS_Blue))
			{
				Clock_Refresh();
			}

			// await press
			while (!Buttons_IsPressed(BUTTONS_Blue))
			{
				if (Buttons_IsPressed(BUTTONS_RightRed))
				{
					Clock_ToggleAlarm();
					_Delay(100); // debounce
					while (Buttons_IsPressed(BUTTONS_RightRed))
					{
						Clock_Refresh();
					}
				}

				Clock_Refresh();
			}

        	Clock_SetNextState();
    	}
    }
}

/* Private functions ---------------------------------------------------------*/

// _OnSysTick()
// ----------
// Decrement the delay counter.
static void _OnSysTick(void)
{
    if (__delay != 0x00)
    {
        __delay--;
    }
}

// _Delay()
// --------
// Delay for a given number of milliseconds.
static void _Delay(uint32_t time)
{
    __delay = time;

    while(__delay != 0);
}